import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import Delivery from 'src/entities/delivery.entity';
import { Repository } from 'typeorm';
import { CreateDeliveryDto, UpdateDeliveryStatusDto } from './delivery.dto';
import { isEmpty } from 'lodash';
import { ApiException } from 'src/core/exceptions/api.exception';
import Job from 'src/entities/job.entity';
import User from 'src/entities/user.entity';
import Resume from 'src/entities/resume.entity';
import Student from 'src/entities/student.entity';

@Injectable()
export class DeliveryService {
  constructor(
    @InjectRepository(Delivery) private deliveryRepository: Repository<Delivery>,
    @InjectRepository(Job) private jobRepository: Repository<Job>,
    @InjectRepository(User) private userRepository: Repository<User>,
    @InjectRepository(Resume) private resumeRepository: Repository<Resume>,
    @InjectRepository(Student) private studentRepository: Repository<Student>,
  ) {}

  // 投递简历
  async create(createDeliveryDto: CreateDeliveryDto) {
    const { userId, jobId } = createDeliveryDto;

    const delivery = await this.deliveryRepository.findOne({
      where: { userId, jobId },
    });

    if (!isEmpty(delivery)) {
      throw new ApiException(12004);
    }

    return await this.deliveryRepository.save(createDeliveryDto);
  }

  // 查询岗位列表
  async findJob(userId: string) {
    const jobIds = await this.deliveryRepository.find({
      where: { userId },
      select: ['jobId', 'userId', 'friendId'],
    });

    // 获取岗位信息
    const jobPromise = jobIds.map(async (item) => {
      return await this.jobRepository
        .createQueryBuilder('job')
        .leftJoinAndSelect('job.position', 'position')
        .leftJoinAndSelect('job.company', 'company')
        .where('job.id = :jobId', { jobId: item.jobId })
        .select([
          'job.id',
          'job.salary',
          'job.experience',
          'job.education',
          'position.name',
          'company.id',
          'company.name',
          'company.scale',
          'company.nature',
        ])
        .getOne();
    });

    // 获取用户信息
    const userPromise = jobIds.map(async (item) => {
      return await this.userRepository.findOne({
        where: { id: item.friendId },
        select: ['avatar', 'nickname', 'id'],
      });
    });

    const jobList = await Promise.all(jobPromise);
    const userList = await Promise.all(userPromise);

    const jobs = jobIds.map((jobId) => {
      const job = jobList.find((job) => job.id === jobId.jobId);
      const user = userList.find((user) => user.id === jobId.friendId);
      return { ...job, user };
    });

    return jobs;
  }

  // 查询投递状态
  async findStatus(id: number) {
    const delivery = await this.deliveryRepository.findOne({ where: { jobId: id } });
    if (isEmpty(delivery)) {
      return false;
    }
    return true;
  }

  // 更新投递简历状态
  async updateStatus(updateDeliveryStatusDto: UpdateDeliveryStatusDto) {
    const { type, userId, id } = updateDeliveryStatusDto;

    if (type === 'all') {
      this.deliveryRepository.update({ friendId: userId }, { status: 1 });
    } else {
      this.deliveryRepository.update(id, { status: 2 });
    }
  }

  // 查询投递用户
  async findUser(id: string) {
    const deliveryList = await this.deliveryRepository.find({ where: { friendId: id } });

    // 获取简历列表和用户列表
    const resumePromises = deliveryList.map(async (item) => {
      const resume = await this.resumeRepository.findOne({
        where: { id: item.resumeId },
        select: ['url'],
      });
      const user = await this.userRepository.findOne({
        where: { id: item.userId },
        select: ['avatar', 'nickname', 'id'],
      });
      const student = await this.studentRepository.findOne({
        where: { userId: user.id },
        select: ['name', 'birth', 'sex', 'major', 'college', 'experience', 'skill'],
      });
      return {
        resume,
        user,
        student,
        delivery: { status: item.status, jobName: item.jobName, deliveryId: item.id },
      };
    });

    const results = await Promise.all(resumePromises);

    return results.map(({ resume, user, student, delivery }) => ({
      ...resume,
      ...user,
      ...student,
      ...delivery,
    }));
  }
}
